package com.bella.api.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bella.api.system.dao.mapper.ext.AuthUserRoleExtendMapper;
import com.bella.api.system.dao.model.AuthUserRole;
import com.bella.api.system.dto.AdminDto;
import com.bella.api.system.dto.user.AdminInfoDto;
import com.bella.api.system.dto.user.AdminQueryDto;
import com.bella.api.system.dto.LoginDto;
import com.bella.api.system.service.UserService;
import com.bella.api.utils.AdminContext;
import com.bella.api.utils.PageResult;
import com.bella.api.system.dao.mapper.ext.AuthUserExtendMapper;
import com.bella.api.system.dao.model.AuthUser;
import com.bella.api.utils.PasswordUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author zsq
 * @create 2020-04-17-17:55
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    AuthUserExtendMapper authUserExtendMapper;
    @Autowired
    AuthUserRoleExtendMapper authUserRoleExtendMapper;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    private final static String REDIS_USER_KEY = "bella:user:";
    private final static long REDIS_TIMEOUT = 1000 * 60 * 60;


    /**
     * 用户登录
     *
     * @param loginDto
     * @return
     */
    @Override
    public AdminDto login(LoginDto loginDto) {
        AuthUser authUser = authUserExtendMapper.login(loginDto.getUserName());
        if (null == authUser || !PasswordUtil.getDigest(loginDto.getPassword()).equalsIgnoreCase(authUser.getPassword())) {
            //用户名或密码错误
            return null;
        }
        AdminDto adminDto = new AdminDto();
        adminDto.setId(authUser.getId());
        adminDto.setToken(UUID.randomUUID().toString().replace("-", ""));
        adminDto.setUserName(authUser.getUserName());
        //设置token有效期为2小时
        try {
            stringRedisTemplate.opsForValue().set(REDIS_USER_KEY + adminDto.getToken(), JSON.toJSON(adminDto).toString(), REDIS_TIMEOUT, TimeUnit.SECONDS);
        } catch (Exception e) {
            //【权限管理】redis存数据失败，账号：" + loginDto.getUserName());
        }
        return adminDto;
    }

    /**
     * 退出登录
     */
    @Override
    public void logout() {
        AdminDto adminDto = AdminContext.get();
        if (null == adminDto) {
            //【权限管理】当前用户不存在
        }
        try {
            stringRedisTemplate.delete(REDIS_USER_KEY + adminDto.getToken());
        } catch (Exception e) {
            //【权限管理】redis删除数据失败，账号：" + loginDto.getUserName());
        }
    }

    /**
     * 获取用户信息
     */
    @Override
    public AdminInfoDto getInfo(Integer id) {
        AuthUser authUser = authUserExtendMapper.selectByPrimaryKey(id);
        AdminInfoDto adminInfoRes = new AdminInfoDto();
        BeanUtils.copyProperties(authUser, adminInfoRes);
        adminInfoRes.setRoleIdList(authUserRoleExtendMapper.getUserRoleByUserId(authUser.getId()));
        return adminInfoRes;
    }

    /**
     * 根据token获取用户信息
     *
     * @param token
     * @return
     */
    @Override
    public AdminDto getAdminByToken(String token) {
        String user = stringRedisTemplate.opsForValue().get(REDIS_USER_KEY + token);
        if (StringUtils.isBlank(user)) {
            return null;
        } else {
            AdminDto admin = JSONObject.parseObject(user, AdminDto.class);
            try {
                //更新token有效期
                stringRedisTemplate.expire(REDIS_USER_KEY + token, REDIS_TIMEOUT, TimeUnit.SECONDS);
            } catch (Exception e) {
//                log.info("redis 异常" + e);
            }
            return admin;
        }
    }

    @Override
    public PageResult getAdminList(AdminQueryDto adminQueryDto) {
        PageHelper.startPage(adminQueryDto.getCurrPage(), adminQueryDto.getPageSize());
        List<AuthUser> adminList = authUserExtendMapper.getAdminList(adminQueryDto.getUserName(), adminQueryDto.getPhone());
        PageInfo pageInfo = new PageInfo<>(adminList);

        PageResult result = new PageResult<>();
        result.setTotalPage(pageInfo.getPages());
        result.setTotalCount(pageInfo.getTotal());
        result.setCurrPage(pageInfo.getPages());
        result.setPageSize(pageInfo.getPageSize());
        result.setList(adminList);
        return result;
    }

    /**
     * 用户新增
     *
     * @param adminInfoDto
     */
    @Override
    @Transactional
    public void addUser(AdminInfoDto adminInfoDto) {
        AuthUser authUser = new AuthUser();
        BeanUtils.copyProperties(adminInfoDto, authUser);
        authUser.setPassword(PasswordUtil.getDigest(adminInfoDto.getUserName()));
        authUser.setTrueName(adminInfoDto.getUserName());
        authUserExtendMapper.insertSelective(authUser);
        if (null != adminInfoDto.getRoleIdList()) {
            batchAddUserRole(authUser.getId(), adminInfoDto.getRoleIdList());
        }
    }

    /**
     * 用户编辑
     *
     * @param adminInfoDto
     */
    @Override
    @Transactional
    public void updateUser(AdminInfoDto adminInfoDto) {
        AuthUser authUser = new AuthUser();
        BeanUtils.copyProperties(adminInfoDto, authUser);
        authUserExtendMapper.updateByPrimaryKeySelective(authUser);

        authUserRoleExtendMapper.deleteByUserId(adminInfoDto.getId());

        if (null != adminInfoDto.getRoleIdList()) {
            batchAddUserRole(authUser.getId(), adminInfoDto.getRoleIdList());
        }
    }

    /**
     * 用户删除
     *
     * @param id
     */
    @Override
    @Transactional
    public void delUser(Integer id) {
        AuthUser authUser = new AuthUser();
        authUser.setId(id);
        authUser.setStatus(0);
        authUserExtendMapper.updateByPrimaryKeySelective(authUser);

        authUserRoleExtendMapper.deleteByUserId(id);
    }

    private void batchAddUserRole(Integer userId, List<Integer> roleIdList) {
        AuthUserRole authUserRole = null;
        List<AuthUserRole> userRoleList = new ArrayList<>();
        for (Integer roleId : roleIdList) {
            authUserRole = new AuthUserRole();
            authUserRole.setUserId(userId);
            authUserRole.setRoleId(roleId);
            userRoleList.add(authUserRole);
        }
        if (roleIdList.size() > 0) {
            authUserRoleExtendMapper.batchAddUserRole(userRoleList);
        }
    }

    @Override
    public void setRedis() {
        stringRedisTemplate.opsForValue().set("bookName","哈利波特");
    }
}
